package database;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;

import exceptions.DBException;
import exceptions.MyException;
import exceptions.TagException;

/* ******************************************************** */
/* 						TagHandler							*/
/*															*/
/*	Takes care of communicating with the database on		*/
/* 	behalf of search tags									*/
/*															*/
/* ******************************************************** */

public class TagHandler extends DBHandler {

	/*
	 * Add Tags To course - add tag and link to course to db
	 */
	public void addTagsToCourse(String[] tags, int courseId) throws MyException {
		// check id
		if (courseId < 0)
			throw new MyException(TagException.BAD_PARAMS);

		List<Integer> tagIds = new LinkedList<Integer>();
		// add all tags to db and save all tags id
		for (String tag : tags) {
			int id = getTagId(tag);
			if (id == -1) {
				Object[][] data = getTagData(tag);
				try {
					id = super.insert(data, Tables.SCHEMA + "."
							+ Tables.Tags.dbName, null);
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			tagIds.add(id);

		}
		// add link from tags to course
		for (int tagId : tagIds) {
			Object[][] data = getCourseToTagData(courseId, tagId);
			try {
				super.insert(data, Tables.SCHEMA + "." + Tables.CourseToTag.dbName, null);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/*
	 * Remove Tags From course - remove tag link to course from db
	 */
	public void removeTagsFromCourse(int courseId) throws MyException {
		System.out.println(courseId);
		// check id
		if (courseId < 0)
			throw new MyException(TagException.BAD_PARAMS);

		// create condition
		String where = Tables.CourseToTag.Columns.COURSE_ID + "="
				+ String.valueOf(courseId);

		// get tags by condition
		ResultSet rs = getTagsResultSet(where);
		if (rs == null) {
			return;
		}

		System.out.println("4");
		// delete rows
		try {
			rs.first();
			rs.deleteRow();
			while (rs.next()) {
				rs.deleteRow();
				System.out.println("5");
			}
			this.closeConnection(rs);
		} catch (SQLException e) {
			throw new DBException(Tables.CourseToTag.dbName,
					"DELETE TAGS FROM COURSE", e.getMessage(),
					DBException.DEFAULT);
		} finally {
			this.closeConnection(rs);
		}
	}

	/* ******* */
	/* Helpers */
	/* ******* */

	/*
	 * get tag data
	 */
	private Object[][] getTagData(String tag) {
		Object[][] data = new Object[1][2];
		data[0][0] = Tables.Tags.Columns.NAME;
		data[0][1] = tag;
		return data;
	}

	/*
	 * get course to tag data
	 */
	private Object[][] getCourseToTagData(int courseId, int tagId) {
		Object[][] data = new Object[2][2];
		data[0][0] = Tables.CourseToTag.Columns.COURSE_ID;
		data[0][1] = courseId;
		data[1][0] = Tables.CourseToTag.Columns.TAG_ID;
		data[1][1] = tagId;
		return data;
	}

	/*
	 * get tags result set (condition: where)
	 */
	private ResultSet getTagsResultSet(String where) throws DBException {
		ResultSet rs = null;
		try {
			rs = super.fetch(Tables.SCHEMA + "."
					+ Tables.CourseToTag.dbName, where, null);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (this.isEmptyResultSet(rs, Tables.SCHEMA + "."
				+ Tables.Course.dbName)) {
			this.closeConnection(rs);
			return null;
		}
		return rs;
	}
	
	/*
	 * Get Tag ID - returns tag id if exists else returns -1
	 */
	private int getTagId(String tag) {
		String where = Tables.Tags.Columns.NAME + "='" + tag+"'";
		ResultSet rs =null;
		int id = -1;
		try {
			rs = super.fetch(Tables.SCHEMA + "." + Tables.Tags.dbName, where,null);
		} catch (Exception e) {
			System.out.println("MOO");
			System.out.println(where);
			return -1;
		}
		try {
			rs.first();
			id = rs.getInt(Tables.Tags.Columns.ID);
			this.closeConnection(rs);
		} catch (Exception e) {
			return -1;
		} finally {
			this.closeConnection(rs);
		}
		return id;
	}
}